#include "arsexpression.h"

/////////// ARSExpr ////////////////////////////////////////////////////////////////////////////////

ARSExpr::ARSExpr(QObject * parent)
    : QObject(parent)
{
}

/////////// ARSExprParseError //////////////////////////////////////////////////////////////////////

ARSExprParseError::ARSExprParseError(QObject * parent)
    : ARSExpr(parent)
{
}

QVariant ARSExprParseError::result() const
{
    return QVariant();
}

bool ARSExprParseError::isNull() const
{
    return true;
}

QString ARSExprParseError::toString() const
{
    return tr("<parse error>");
}

QString ARSExprParseError::symbol() const
{
    return QString();
}

/////////// ARSConst ///////////////////////////////////////////////////////////////////////////////

ARSExprConst::ARSExprConst(QVariant var, QObject * parent)
    : ARSExpr(parent)
{
    m_var = var;
}

void ARSExprConst::setVar(QVariant var)
{
    m_var = var;
}

QVariant ARSExprConst::var() const
{
    return m_var;
}

QVariant ARSExprConst::result() const
{
    return m_var;
}

bool ARSExprConst::isNull() const
{
    return m_var.isNull();
}

QString ARSExprConst::toString() const
{
    return m_var.toString();
}

QString ARSExprConst::symbol() const
{
    return QString();
}

/////////// ARSExprField ///////////////////////////////////////////////////////////////////////////

ARSExprField::ARSExprField(int fieldID, FieldState state, QObject * parent)
    : ARSExpr(parent)
{
    m_fieldID = fieldID;
    m_fieldState = state;
}

void ARSExprField::setFieldID(int field)
{
    m_fieldID = field;
}

int ARSExprField::fieldID() const
{
    return m_fieldID;
}

void ARSExprField::setFieldState(FieldState state)
{
    m_fieldState = state;
}

ARSExprField::FieldState ARSExprField::fieldState() const
{
    return m_fieldState;
}

QVariant ARSExprField::result() const
{
    return m_fieldID;
}

bool ARSExprField::isNull() const
{
     return m_fieldID == -1;
}

QString ARSExprField::toString() const
{
    QString prefix;
    switch(m_fieldState)
    {
        case Database:
            prefix = "DB.";
            break;

        case Transaction:
            prefix = "TR.";
            break;

        default:
            prefix = QString();
    }

    return "'" + prefix + fieldID() + "'";
}

QString ARSExprField::symbol() const
{
    return QString();
}

/////////// ARSExprNot /////////////////////////////////////////////////////////////////////////////

ARSExprNot::ARSExprNot(ARSExpr * child, QObject * parent)
    : ARSExpr(parent)
{
    m_child = child;
}

void ARSExprNot::setChild(ARSExpr * child)
{
    m_child = child;
}

ARSExpr * ARSExprNot::child() const
{
    return m_child;
}

QVariant ARSExprNot::result() const
{
    if(isNull())
        return QVariant();

    return !m_child->result().toBool();
}

bool ARSExprNot::isNull() const
{
    return m_child == 0;
}

QString ARSExprNot::toString() const
{
    if(isNull())
        return QString();

    return symbol() + " (" + m_child->toString() + ")";
}

QString ARSExprNot::symbol() const
{
    return "NOT";
}

/////////// ARSExprBinary //////////////////////////////////////////////////////////////////////////

ARSExprBinary::ARSExprBinary(ARSExpr * left, ARSExpr * right, QObject * parent)
    : ARSExpr(parent)
{
    m_left = left;
    m_right = right;
}

void ARSExprBinary::setLeft(ARSExpr * left)
{
    m_left = left;
}

ARSExpr * ARSExprBinary::left() const
{
    return m_left;
}

void ARSExprBinary::setRight(ARSExpr * right)
{
    m_right = right;
}

ARSExpr * ARSExprBinary::right() const
{
    return m_right;
}

bool ARSExprBinary::isNull() const
{
    return (m_left == 0) || (m_right == 0);
}

QString ARSExprBinary::toString() const
{
    if(isNull())
        return QString();

    return m_left->toString() + " " + symbol() + " " + m_right->toString();
}

/////////// ARSExprAnd /////////////////////////////////////////////////////////////////////////////

ARSExprAnd::ARSExprAnd(ARSExpr *left, ARSExpr *right, QObject *parent)
    : ARSExprBinary(left, right, parent)
{
}

QVariant ARSExprAnd::result() const
{
    if(isNull())
        return QVariant();

    return m_left->result().toBool() && m_right->result().toBool();
}

/////////// ARSExprOr //////////////////////////////////////////////////////////////////////////////

ARSExprOr::ARSExprOr(ARSExpr *left, ARSExpr *right, QObject *parent)
    : ARSExprBinary(left, right, parent)
{
}

QVariant ARSExprOr::result() const
{
    if(isNull())
        return QVariant();

    return m_left->result().toBool() || m_right->result().toBool();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
